package top.scsoul.pas.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import top.scsoul.pas.bean.AchievementImportExcelL;
import top.scsoul.pas.bean.AchievementImportExcelW;
import top.scsoul.pas.bean.ClazzPerformanceAnalysisBean;
import top.scsoul.pas.entity.Achievement;
import top.scsoul.pas.entity.Clazz;
import top.scsoul.pas.entity.ExamInfo;
import top.scsoul.pas.entity.Student;
import top.scsoul.pas.repository.AchievementRepository;
import top.scsoul.pas.service.AchievementService;
import top.scsoul.pas.service.ExamInfoService;
import top.scsoul.pas.service.StudentService;
import top.scsoul.pas.utils.ExcelUtil;
import top.scsoul.pas.utils.PerformanceAnalysisUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author cbt28
 */
@Slf4j
@Controller
public class AchievementController {
    @Autowired
    AchievementService achievementService;

    @Autowired
    ExamInfoService examInfoService;
    @Autowired
    StudentService studentService;

    @Autowired
    AchievementRepository achievementRepository;

    /**
     * 根据考试id 获取成绩单页面
     *
     * @param id
     * @return
     */
    @RequestMapping("achievement/school_report_clazz")
    public String schoolReportClazz(Long id, Model model) {
        List<Achievement> achievementList = achievementService.listAchievementByExamInfoId(id);
        model.addAttribute("achievementList", achievementList);
        ExamInfo examInfo = examInfoService.findById(id);
        model.addAttribute("examInfo", examInfo);
        List<ClazzPerformanceAnalysisBean> clazzPerformanceAnalysisBeans = null;
        try {
            clazzPerformanceAnalysisBeans = PerformanceAnalysisUtil.ClazzPerformanceAnalysis(achievementList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        model.addAttribute("clazzPerformanceAnalysisBeans", clazzPerformanceAnalysisBeans);
        return "school_report";
    }

    /**
     * 成绩导入页面
     *
     * @param id 考试 id
     * @return
     */
    @RequestMapping("achievement/importAchievementPage")
    public String importAchievementPage(Long id, Model model) {
        ExamInfo examInfo = examInfoService.findById(id);
        model.addAttribute("examInfo", examInfo);
        return "import_achievement";
    }

    /**
     * 教师下载学生成绩导入模板
     *
     * @param id
     * @param httpResponse
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("achievement/downloadClazzXls")
    public void downloadClazzXls(Long id, HttpServletResponse httpResponse) throws Exception {
        ExamInfo examInfo = examInfoService.findById(id);
        Clazz clazz = examInfo.getClazzes().get(0);
        Integer type = clazz.getType();
        Long clazzId = clazz.getId();
        Workbook workbook = null;
        List<Student> studentList = studentService.getStudentsByClazzId(clazzId);
        String name = examInfo.getName() + "成绩导入模板";
        try {
            if (type == 0) {
                List<AchievementImportExcelW> list = new ArrayList<>();
                studentList.forEach(student -> {
                    AchievementImportExcelW achievementImportExcelW = new AchievementImportExcelW();
                    achievementImportExcelW.setStudentId(student.getId());
                    achievementImportExcelW.setStudentName(student.getName());
                    list.add(achievementImportExcelW);
                });
                ExportParams exportParams = new ExportParams(name, name, ExcelType.XSSF);
                workbook = ExcelExportUtil.exportBigExcel(exportParams, AchievementImportExcelW.class, list);
            } else if (type == 1) {
                List<AchievementImportExcelL> list = new ArrayList<>();
                studentList.forEach(student -> {
                    AchievementImportExcelL achievementImportExcelL = new AchievementImportExcelL();
                    achievementImportExcelL.setStudentId(student.getId());
                    achievementImportExcelL.setStudentName(student.getName());
                    list.add(achievementImportExcelL);
                });


                ExportParams exportParams = new ExportParams(name, name, ExcelType.XSSF);
                workbook = ExcelExportUtil.exportBigExcel(exportParams, AchievementImportExcelL.class, list);
            }

        } finally {
            if (workbook != null) {
                //此处必须要关闭，否则会导致stream closed异常
                ExcelExportUtil.closeExportBigExcel();
            }
        }


        try (ByteArrayOutputStream os = new ByteArrayOutputStream(1024)) {
            assert workbook != null;
            workbook.write(os);
            ExcelUtil.writeIO(httpResponse, os, name);
        } catch (IOException e) {
            throw new Exception("导出报表失败");
        }
    }

    /**
     * 教师导入本班学生考试成绩
     *
     * @param id
     * @param multipartFile
     * @param response
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("achievement/uploadClazzXls")
    public void uploadClazzXls(Long id, @RequestParam("file") MultipartFile multipartFile, HttpServletResponse response) throws Exception {
        response.setCharacterEncoding("utf-8");
        long size = multipartFile.getSize();
        if (size <= 0) {
            response.getWriter().write("空！");
            return;
        }

        ExamInfo examInfo = examInfoService.findById(id);
        Clazz clazz = examInfo.getClazzes().get(0);
        Integer type = clazz.getType();

        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        params.setTitleRows(1);
        if (type == 0) {
            List<AchievementImportExcelW> result = null;
            result = ExcelImportUtil.importExcel(multipartFile.getInputStream(),
                    AchievementImportExcelW.class, params);
            result.forEach(item -> {
                Student student = studentService.queryById(item.getStudentId());
                Achievement achievement = new Achievement();
                achievement
                        .setChinese(item.getChinese())
                        .setMath(item.getMath())
                        .setEnglish(item.getEnglish())
                        .setPolitics(item.getPolitics())
                        .setHistory(item.getHistory())
                        .setGeography(item.getGeography())
                        .setExamInfo(examInfo)
                        .setStudent(student);
                achievementRepository.save(achievement);
            });


        } else if (type == 1) {
            List<AchievementImportExcelL> result = null;
            result = ExcelImportUtil.importExcel(multipartFile.getInputStream(),
                    AchievementImportExcelL.class, params);
            result.forEach(item -> {
                Student student = studentService.queryById(item.getStudentId());
                Achievement achievement = new Achievement();
                achievement
                        .setChinese(item.getChinese())
                        .setMath(item.getMath())
                        .setEnglish(item.getEnglish())
                        .setPhysics(item.getPhysics())
                        .setChemistry(item.getChemistry())
                        .setBiology(item.getBiology())
                        .setExamInfo(examInfo)
                        .setStudent(student);
                achievementRepository.save(achievement);
            });
        }
        response.getWriter().write("导入成功！");
    }
}
